package com.kifas.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.kifas.entity.AkunMasterEntity;
import com.kifas.entity.BukuHutangEntity;
import com.kifas.entity.BukuPiutangEntity;
import com.kifas.entity.HutangEntity;
import com.kifas.entity.PiutangEntity;
import com.kifas.model.xml.AkunMasterModel;
import com.kifas.model.xml.BukuHutangModel;
import com.kifas.model.xml.BukuPiutangModel;
import com.kifas.model.xml.PersistStatus;
import com.kifas.model.xml.TypeAkunModel;
import com.kifas.service.EntityServiceManager;

@Component
@Scope("prototype")
@Path("/Buku")
public class BukuController {

	private static Logger log = Logger.getLogger(BukuController.class);

	@Context
	UriInfo uriInfo;

	@Autowired
	private EntityServiceManager entityManager;

	@POST
	@Path("Piutang")
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public PersistStatus insertBukuPiutang(JAXBElement<BukuPiutangModel> xml) {
		BukuPiutangModel model = xml.getValue();
		PiutangEntity piutang = entityManager.getPiutang(model.getIdPiutang());
		AkunMasterEntity akunMaster = entityManager.getAkunMaster(model.getAkunMaster().getKodeAkun());
		BukuPiutangEntity previous = entityManager.getLatestBukuPiutang(piutang);
		BigDecimal newSisaBayar = previous.getSisaBayar().add(model.getDebet()).min(model.getKredit());
		if (newSisaBayar.compareTo(new BigDecimal(0)) < 0) {
			return new PersistStatus("BukuPiutangEntity", "failed", "Sisa bayar not valid");
		}
		BukuPiutangEntity bukuPiutang = new BukuPiutangEntity(null, akunMaster, piutang, model.getDebet(), model.getKredit(), model.getTanggal(),
				model.getKeterangan(), model.getPosting(), model.getNoFaktur(), model.getDeskripsi(), newSisaBayar, model.getCreatedBy(),
				model.getCreatedDate());
		try {
			entityManager.persist(bukuPiutang);
		} catch (Exception e) {
			log.error("can not persist buku piutang", e);
			return new PersistStatus("BukuPiutangEntity", "failed", "can not persist Buku Piutang Entity");
		}
		return new PersistStatus("BukuPiutangEntity", "success");
	}

	@GET
	@Path("Piutang/Unpost")
	@Produces(MediaType.TEXT_XML)
	public List<BukuPiutangModel> getPiutangUnpost() {
		return transformPiutang(entityManager.getBukuPiutangs(false));
	}

	@POST
	@Path("Hutang")
	@Produces(MediaType.APPLICATION_XML)
	@Consumes(MediaType.APPLICATION_XML)
	public PersistStatus insertBukuHutang(JAXBElement<BukuHutangModel> xml) {
		BukuHutangModel model = xml.getValue();
		HutangEntity hutang = entityManager.getHutang(model.getIdHutang());
		AkunMasterEntity akunMaster = entityManager.getAkunMaster(model.getAkunMaster().getKodeAkun());
		BukuHutangEntity previous = entityManager.getLatestBukuHutang(hutang);
		BigDecimal newSisaBayar = previous.getSisaBayar().add(model.getKredit()).min(model.getDebet());
		if (newSisaBayar.compareTo(new BigDecimal(0)) < 0) {
			return new PersistStatus("BukuPiutangEntity", "failed", "Sisa bayar not valid");
		}
		BukuHutangEntity bukuHutang = new BukuHutangEntity(null, akunMaster, hutang, model.getDebet(), model.getKredit(), model.getTanggal(),
				model.getKeterangan(), model.getPosting(), model.getNoFaktur(), model.getDeskripsi(), newSisaBayar, model.getCreatedBy(),
				model.getCreatedDate());
		try {
			entityManager.persist(bukuHutang);
		} catch (Exception e) {
			log.error("can not persist buku hutang", e);
			return new PersistStatus("BukuHutangEntity", "failed", "can not persist Buku Hutang Entity");
		}
		return new PersistStatus("BukuHutangEntity", "success");
	}

	@GET
	@Path("Hutang/Unpost")
	@Produces(MediaType.TEXT_XML)
	public List<BukuHutangModel> getHutangUnpost() {
		return transformHutang(entityManager.getBukuHutangs(false));
	}

	private List<BukuPiutangModel> transformPiutang(List<BukuPiutangEntity> bukuPiutangs) {
		List<BukuPiutangModel> bukuPiutangModels = new ArrayList<BukuPiutangModel>();
		for (BukuPiutangEntity bp : bukuPiutangs) {
			TypeAkunModel typeAkun = new TypeAkunModel(bp.getAkunMaster().getTypeAkun().getIdType(), bp.getAkunMaster().getTypeAkun().getNama(), bp
					.getAkunMaster().getTypeAkun().getDeskripsi(), bp.getAkunMaster().getTypeAkun().getKode(), bp.getAkunMaster().getTypeAkun().getCreatedBy());
			AkunMasterModel akunMaster = new AkunMasterModel(bp.getAkunMaster().getKodeAkun(), bp.getAkunMaster().getNama(), bp.getAkunMaster().getDk(), bp
					.getAkunMaster().getIdParentAkun(), bp.getAkunMaster().isActive(), bp.getAkunMaster().getDeskripsi(), bp.getAkunMaster().getNamaPanjang(),
					typeAkun, bp.getCreatedBy());
			bukuPiutangModels.add(new BukuPiutangModel(bp.getIdBukuPiutang(), akunMaster, bp.getDebet(), bp.getKredit(), bp.getTanggal(), bp.getKeterangan(),
					bp.getPosting(), bp.getNoFaktur(), bp.getDeskripsi(), bp.getSisaBayar(), bp.getCreatedBy(), bp.getCreatedDate()));
		}
		return bukuPiutangModels;
	}

	private List<BukuHutangModel> transformHutang(List<BukuHutangEntity> bukuHutangs) {
		List<BukuHutangModel> bukuHutangModels = new ArrayList<BukuHutangModel>();
		for (BukuHutangEntity bh : bukuHutangs) {
			TypeAkunModel typeAkun = new TypeAkunModel(bh.getAkunMaster().getTypeAkun().getIdType(), bh.getAkunMaster().getTypeAkun().getNama(), bh
					.getAkunMaster().getTypeAkun().getDeskripsi(), bh.getAkunMaster().getTypeAkun().getKode(), bh.getAkunMaster().getTypeAkun().getCreatedBy());
			AkunMasterModel akunMaster = new AkunMasterModel(bh.getAkunMaster().getKodeAkun(), bh.getAkunMaster().getNama(), bh.getAkunMaster().getDk(), bh
					.getAkunMaster().getIdParentAkun(), bh.getAkunMaster().isActive(), bh.getAkunMaster().getDeskripsi(), bh.getAkunMaster().getNamaPanjang(),
					typeAkun, bh.getCreatedBy());
			bukuHutangModels.add(new BukuHutangModel(bh.getIdBukuHutang(), akunMaster, bh.getDebet(), bh.getKredit(), bh.getTanggal(), bh.getKeterangan(),
					bh.getPosting(), bh.getNoFaktur(), bh.getDeskripsi(), bh.getSisaBayar(), bh.getCreatedBy(), bh.getCreatedDate()));
		}
		return bukuHutangModels;
	}
}
